// 1-1-9 日期与时间-函数-9

/**
 * C++ 标准库没有提供所谓的日期类型。C++ 继承了 C 语言用于日期和时间操作的结构和函数。为了使用日期和时间相关的函数和结构，需要在 C++ 程序中引用 <ctime> 头文件。
 * 
 * 有四个与时间相关的类型：clock_t、time_t、size_t 和 tm。类型 clock_t、size_t 和 time_t 能够把系统时间和日期表示为某种整数。
 * 
 * 结构类型 tm 把日期和时间以 C 结构的形式保存，tm 结构的定义如下：
    struct tm {
      int tm_sec;   // 秒，正常范围从 0 到 59，但允许至 61
      int tm_min;   // 分，范围从 0 到 59
      int tm_hour;  // 小时，范围从 0 到 23
      int tm_mday;  // 一月中的第几天，范围从 1 到 31
      int tm_mon;   // 月，范围从 0 到 11
      int tm_year;  // 自 1900 年起的年数
      int tm_wday;  // 一周中的第几天，范围从 0 到 6，从星期日算起
      int tm_yday;  // 一年中的第几天，范围从 0 到 365，从 1 月 1 日算起
      int tm_isdst; // 夏令时
    };
 *
 * 下面是 C/C++ 中关于日期和时间的重要函数。所有这些函数都是 C/C++ 标准库的组成部分，您可以在 C++ 标准库中查看一下各个函数的细节。
 * 
 * 1. time_t time(time_t *time);
 * 该函数返回系统的当前日历时间，自 1970 年 1 月 1 日以来经过的秒数。如果系统没有时间，则返回 -1。
 * 
 * 2. char *ctime(const time_t *time);
 * 该返回一个表示当地时间的字符串指针，字符串形式 day month year hours:minutes:seconds year\n\0。
 * 
 * 3. struct tm *localtime(const time_t *time);
 * 该函数返回一个指向表示本地时间的 tm 结构的指针。
 * 
 * 4. clock_t clock(void);
 * 该函数返回程序执行起（一般为程序的开头），处理器时钟所使用的时间。如果时间不可用，则返回 -1。
 * 
 * 5. char * asctime ( const struct tm * time );
 * 该函数返回一个指向字符串的指针，字符串包含了 time 所指向结构中存储的信息，返回形式为：day month date hours:minutes:seconds year\n\0。
 * 
 * 6. struct tm *gmtime(const time_t *time);
 * 该函数返回一个指向 time 的指针，time 为 tm 结构，用协调世界时（UTC）也被称为格林尼治标准时间（GMT）表示。
 * 
 * 7. time_t mktime(struct tm *time);
 * 该函数返回日历时间，相当于 time 所指向结构中存储的时间。
 * 
 * 8. double difftime ( time_t time2, time_t time1 );
 * 该函数返回 time1 和 time2 之间相差的秒数。
 * 
 * 9. size_t strftime();
 * 该函数可用于格式化日期和时间为指定的格式。
 * 
*/

#include <iostream>
#include <ctime>
// #include <stdio.h>
#define BST (+1)
#define CCT (+8)

int main(void)
{

  /**
   * 9. size_t strftime();
   * 
   * 描述
   * C 库函数 size_t strftime(char *str, size_t maxsize, const char *format, const struct tm *timeptr) 根据 format 中定义的格式化规则，格式化结构 timeptr 表示的时间，并把它存储在 str 中。
   * 
   * 参数
      str -- 这是指向目标数组的指针，用来复制产生的 C 字符串。
      maxsize -- 这是被复制到 str 的最大字符数。
      format -- 这是 C 字符串，包含了普通字符和特殊格式说明符的任何组合。这些格式说明符由函数替换为表示 tm 中所指定时间的相对应值。格式
      说明符是：
    说明符     替换为                  实例
      %a	缩写的星期几名称	          Sun
      %A	完整的星期几名称	          Sunday
      %b	缩写的月份名称	            Mar
      %B	完整的月份名称	            March
      %c	日期和时间表示法	          Sun Aug 19 02:56:02 2012
      %d	一月中的第几天（01-31）	    19
      %H	24 小时格式的小时（00-23）	14
      %I	12 小时格式的小时（01-12）	05
      %j	一年中的第几天（001-366）	  231
      %m	十进制数表示的月份（01-12）	08
      %M	分（00-59）	               55
      %p	AM 或 PM 名称	             PM
      %S	秒（00-61）	               02
      %U	一年中的第几周，以第一个     
星期日作为第一周的第一天（00-53）	     33
      %w	十进制数表示的星期几，
星期日表示为 0（0-6）	                4
      %W	一年中的第几周，以第一个
星期一作为第一周的第一天（00-53）	     34
      %x	日期表示法	                08/19/12
      %X	时间表示法	                02:50:06
      %y	年份，最后两个数字（00-99）	 01
      %Y	年份	                     2012
      %Z	时区的名称或缩写	          CDT
      %%	一个 % 符号	                %

  *   
  * timeptr -- 这是指向 tm 结构的指针，该结构包含了一个被分解为以下各部分的日历时间：
      struct tm {
        int tm_sec;         // 秒，范围从 0 到 59                
        int tm_min;         // 分，范围从 0 到 59                
        int tm_hour;        // 小时，范围从 0 到 23                
        int tm_mday;        // 一月中的第几天，范围从 1 到 31                    
        int tm_mon;         // 月份，范围从 0 到 11                
        int tm_year;        // 自 1900 起的年数                
        int tm_wday;        // 一周中的第几天，范围从 0 到 6                
        int tm_yday;        // 一年中的第几天，范围从 0 到 365                    
        int tm_isdst;       // 夏令时                            
      };

  * 返回值
  * 如果产生的 C 字符串小于 size 个字符（包括空结束字符），则会返回复制到 str 中的字符总数（不包括空结束字符），否则返回零。
  */
  std::cout << "\n----9. size_t strftime()----" << std::endl;

  time_t t;
  struct tm info;
  struct tm *ptr;
  const int size = 20;

  time(&t);
  ptr = localtime(&t);

  int len;
  char str[size];
  len = strftime(str, size, "%Y-%m-%d %H:%M:%S", ptr);

  if (len == 0)
  {
    std::cout << "the size is not enough！ "
              << " size : " << size << " len : " << len << " str : " << str << std::endl;
  }
  else
  {
    std::cout << " size : " << size << " len : " << len
              << " str : " << str << std::endl;
  }

  printf("--------------end---------------\n");
  // system("pause");
  return 0;
}